/**
 * @file gc.h
 * @brief VimL虚拟机垃圾回收系统
 * @author VimL VM Team
 * @date 2024
 * 
 * 提供分代增量式垃圾回收器，支持小对象池和字符串驻留
 */

#pragma once

#include <vector>
#include <unordered_set>
#include <memory>
#include <mutex>
#include "value.h"

namespace viml {

// 对象类型
enum class ObjectType {
    STRING,
    LIST,
    DICT,
    FUNCTION,
    CLOSURE,
    OTHER
};

// 对象头部
struct ObjectHeader {
    ObjectType type;
    bool marked;
    bool in_young_gen;
    size_t size;
    ObjectHeader* next;
    
    ObjectHeader(ObjectType t, size_t s) 
        : type(t), marked(false), in_young_gen(true), size(s), next(nullptr) {}
};

// 垃圾回收器配置
struct GCConfig {
    size_t young_gen_threshold = 1024 * 1024;  // 1MB
    size_t old_gen_threshold = 10 * 1024 * 1024; // 10MB
    size_t heap_growth_factor = 2;
    bool enable_incremental = true;
    bool enable_generational = true;
};

// 小对象池
class ObjectPool {
public:
    ObjectPool(size_t object_size, size_t pool_size = 1024);
    ~ObjectPool();
    
    void* allocate();
    void deallocate(void* ptr);
    void reset();
    size_t object_size() const { return object_size_; }
    
private:
    struct Chunk {
        char* data;
        Chunk* next;
    };
    
    size_t object_size_;
    size_t pool_size_;
    Chunk* current_chunk_;
    char* free_list_;
    size_t offset_;
    std::mutex mutex_;
};

// 字符串驻留池
class StringInternPool {
public:
    StringInternPool();
    ~StringInternPool();
    
    std::shared_ptr<std::string> intern(const std::string& str);
    void cleanup();
    size_t size() const { return strings_map_.size(); }
    
private:
    std::unordered_map<std::string, std::shared_ptr<std::string>> strings_map_;
    mutable std::mutex mutex_;
};

// 垃圾回收器
class GarbageCollector {
public:
    GarbageCollector(const GCConfig& config = GCConfig{});
    ~GarbageCollector();
    
    // 内存分配
    void* allocate(size_t size, ObjectType type);
    
    // 垃圾回收
    void collect();
    void collect_young_gen();
    void collect_old_gen();
    void incremental_collect();
    
    // 根对象管理
    void add_root(Value* value);
    void remove_root(Value* value);
    
    // 统计信息
    size_t heap_size() const { return heap_size_; }
    size_t objects_count() const { return objects_count_; }
    size_t young_gen_size() const { return young_gen_size_; }
    size_t old_gen_size() const { return old_gen_size_; }
    
    // 调试信息
    void print_stats() const;
    void verify_heap() const;
    
    // 字符串驻留
    std::shared_ptr<std::string> intern_string(const std::string& str);
    
private:
    // 内存管理
    void* allocate_from_pool(size_t size, ObjectType type);
    void* allocate_from_heap(size_t size, ObjectType type);
    
    // 标记阶段
    void mark_roots();
    void mark_value(const Value& value);
    void mark_object(ObjectHeader* obj);
    
    // 清除阶段
    void sweep();
    void sweep_generation(bool young_gen);
    
    // 对象晋升
    void promote_objects();
    
    // 小对象池
    ObjectPool* get_pool(size_t size);
    
    GCConfig config_;
    
    // 堆管理
    ObjectHeader* young_gen_head_;
    ObjectHeader* old_gen_head_;
    size_t heap_size_;
    size_t young_gen_size_;
    size_t old_gen_size_;
    size_t objects_count_;
    
    // 根对象
    std::vector<Value*> roots_;
    std::mutex roots_mutex_;
    
    // 小对象池
    std::vector<std::unique_ptr<ObjectPool>> pools_;
    
    // 字符串驻留池
    std::unique_ptr<StringInternPool> string_pool_;
    
    // 统计信息
    mutable size_t collections_count_;
    mutable size_t young_gen_collections_;
    mutable size_t old_gen_collections_;
    mutable size_t bytes_freed_;
};

// 全局GC实例
extern std::unique_ptr<GarbageCollector> g_gc;

// 初始化和清理函数
void initialize_gc();
void shutdown_gc();

// 辅助函数
inline void* gc_allocate(size_t size, ObjectType type) {
    return g_gc->allocate(size, type);
}

inline std::shared_ptr<std::string> gc_intern_string(const std::string& str) {
    return g_gc->intern_string(str);
}

} // namespace viml